﻿using AutoStar.Common;
using AutoStar.Models;
using AutoStar.Views;
using AutoStar.Views.Pages;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using SharpGL.SceneGraph;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using static AutoStar.Models.PrintSliceModel;

namespace AutoStar.ViewModel
{
    public class PrintSliceVM : BaseViewModel
    {
        public PrintSliceVM()
        {
            AddCommand = new RelayCommand(Add);
            DeleteCommand = new RelayCommand(Delete);
            EditCommand = new RelayCommand(Edit);
            MoveDownCommand = new RelayCommand(MoveDown);
            MoveUpCommand = new RelayCommand(MoveUp);
            DeleteAllCommand = new RelayCommand(DeleteAll);
            EditAllCommand = new RelayCommand(EditAll);

            SetCuringLampCommand = new RelayCommand(SetCuringLamp);
            SetAllCuringLampCommand = new RelayCommand(SetAllCuringLamp);
            PrintCurrentLayerCommand = new RelayCommand(PrintCurrentLayer);
            PrintAllLayerCommand = new RelayCommand(PrintAllLayer);
            GoHomeCommand = new RelayCommand(GoHome);
            PausePrintCommand = new RelayCommand(PausePrint);
            EndPrintCommand = new RelayCommand(EndPrint);
            CellClick = new RelayCommand(CellClickExecute);
        }


        private void SetAllCuringLamp()
        {
            bool isAllCuringLamp = Global.printProject.printLayers.All(layer => layer.CuringLamp);
            if (Global.printProject.printLayers.All(layer => layer.CuringLamp))
            {
                if (MessageBox.Show("是否取消全部层固化灯", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    foreach (var layer in Global.printProject.printLayers)
                    {
                        layer.CuringLamp = false;
                    }
                }
            }
            else
            {
                if (MessageBox.Show("是否设置全部层固化灯", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    foreach (var layer in Global.printProject.printLayers)
                    {
                        layer.CuringLamp = true;
                    }
                }
            }
            Global.MainVM.flushDgv();
        }

        private void SetCuringLamp()
        {
            if (Global.printProject.printLayers[Global.printer.layerIndex].CuringLamp)
            {
                if (MessageBox.Show("是否取消当前层固化灯设置", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    Global.printProject.printLayers[Global.printer.layerIndex].CuringLamp = false;
            }
            else
                Global.printProject.printLayers[Global.printer.layerIndex].CuringLamp = true;
            Global.MainVM.flushDgv();
        }
        private void EditAll()
        {
            if (Global.printProject.printLayers.Count == 0)
            {
                MessageBox.Show("无数据!");
                return;
            }
            DialogResult RSS = MessageBox.Show("确定要编辑全部层吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            switch (RSS)
            {
                case DialogResult.Yes:
                    IsEnbaled = true;
                    WindowLayer editLayer = new WindowLayer(Global.printProject.printLayers[Global.printer.layerIndex]);
                    editLayer.AddLayerEvent += EditAllLayer_AddLayerEvent;
                    editLayer.ShowDialog();
                    //Global.printProject.printLayers[Global.printer.layerIndex] = layerChanged;
                    //Global.MainVM.flushDgv();
                    break;
                case DialogResult.No:
                    break;
            }
            IsEnbaled = false;
        }

        public void EditAllLayer_AddLayerEvent(PrintLayer layerChanged)
        {
            for (int i = 0; i < Global.printProject.printLayers.Count; i++)
            {
                Global.printProject.printLayers[i].x_start = layerChanged.x_start;
                Global.printProject.printLayers[i].y_start = layerChanged.y_start;
                Global.printProject.printLayers[i].channel = layerChanged.channel;
                Global.MainVM.flushDgvNew(layerChanged);
            }
            //Global.printProject.printLayers[Global.printer.layerIndex] = layerChanged;
            //Global.MainVM.flushDgvNew(layerChanged);
        }
        private void DeleteAll()
        {
            if (Global.printProject.printLayers.Count == 0)
            {
                MessageBox.Show("无数据!");
                return;
            }
            DialogResult RSS = MessageBox.Show("确定要全部删除吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            switch (RSS)
            {
                case DialogResult.Yes:
                    ImageSource = null;
                    Global.printProject.printLayers = new List<PrintLayer>();
                    Global.printer.layerIndex = -1;
                    flushDgv();
                    break;
                case DialogResult.No:
                    break;
            }
        }

        private void CellClickExecute()
        {
            if (Global.printer.printerState != 0)
            {
                MessageBox.Show("正在打印中，不能切换层");
                return;
            }
            changeLayer(DataGridLists[Global.printer.layerIndex + 1].层序号);
        }

        public void Add()
        {
            if (Global.printProject != null)
            {
                WindowLayer addLayer = Global.WindowLayer;
                if (Global.printProject.printLayers.Count == 0)
                {
                    addLayer = new WindowLayer(new PrintLayer(0, 0, 2, 20, 20, 0, 0, 0, 0, 0.1f));
                }
                else
                {
                    addLayer = new WindowLayer(Global.printProject.printLayers[Global.printProject.printLayers.Count - 1]);
                }
                addLayer.AddLayerEvent += AddLayer_AddLayerEvent;
                addLayer.ShowDialog();
            }
        }
        public void AddLayer_AddLayerEvent(PrintLayer layerChanged)
        {
            Global.printProject.printLayers.Add(layerChanged);
            Global.MainVM.flushDgv();
            if (Global.printProject.printLayers.Count == 1)
            {
                changeLayer(0);
            }
        }
        //List<Line3D> lines = new List<Line3D>();//用于在状态监测界面画路径的线
        List<Line3D> lines = Global.lines;
        public void flushDgv()//刷新打印层的dgv
        {
            lines.Clear();
            Global.SliceVM.DataGridLists = new System.Collections.ObjectModel.ObservableCollection<PrintSliceItem>();
            Global.SliceVM.DataGridLists.Clear();
            int i = 0;
            foreach (var layer in Global.printProject.printLayers)
            {
                var item = new PrintSliceItem
                {
                    层序号 = i + 1,
                    打印类型 = GetPrintModeString(layer.mode),
                    打印通道 = layer.channel + 1,
                    固化灯 = layer.CuringLamp ? "开" : "关",
                };
                i++;
                Global.SliceVM.DataGridLists.Add(item);
            }
        }
        private string GetPrintModeString(int mode)
        {
            switch (mode)
            {
                case 0: return "蛇形";
                case 1: return "回形";
                case 2: return "网格形";
                case 10: return "纵向填充";
                case 11: return "横向填充";
                case 12: return "横向纵横交替填充";
                default: return "未知";
            }
        }
        private void Delete()
        {
            if (Global.printProject.printLayers.Count == 0)
            {
                MessageBox.Show("无数据!");
                return;
            }
            SelectedIndices.Reverse();
            foreach (var index in SelectedIndices)
            {
                if (index >= 0 && index < Global.printProject.printLayers.Count)
                {
                    Global.printProject.printLayers.RemoveAt(index);
                }
            }
            if (Global.printProject.printLayers.Count == 0)
            {
                Global.printer.layerIndex = -1;
                ImageSource = null;
            }
            else
            {
                changeLayer(0);
            }
            Global.MainVM.flushDgv();

            //DialogResult RSS = MessageBox.Show("确定要删除选中行数据码？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

            //var dd = SelectedIndices;
            //switch (RSS)
            //{
            //    case DialogResult.Yes:
            //        Global.printProject.printLayers.RemoveAt(Global.printer.layerIndex);
            //        if (Global.printProject.printLayers.Count == 0)
            //        {
            //            Global.printer.layerIndex = -1;
            //            ImageSource = null;
            //        }
            //        else
            //        {
            //            changeLayer(0);
            //        }
            //        Global.MainVM.flushDgv();
            //        break;
            //    case DialogResult.No:
            //        break;
            //}
        }

        private void Edit()
        {
            if (Global.printProject.printLayers.Count == 0)
            {
                MessageBox.Show("无数据!");
                return;
            }
            WindowLayer editLayer = new WindowLayer(Global.printProject.printLayers[Global.printer.layerIndex]);
            editLayer.AddLayerEvent += EditLayer_AddLayerEvent;
            editLayer.ShowDialog();
        }
        public void EditLayer_AddLayerEvent(PrintLayer layerChanged)
        {
            Global.printProject.printLayers[Global.printer.layerIndex] = layerChanged;
            Global.MainVM.flushDgv();
        }


        private void MoveDown()
        {
            try
            {
                if (Global.printProject.printLayers.Count == 0)
                {
                    MessageBox.Show("无数据!");
                    return;
                }
                if (Global.printer.layerIndex == 0)
                {
                    MessageBox.Show("已经是第一行了!");
                    return;
                }
                Global.printProject.printLayers.Insert(Global.printer.layerIndex - 1, Global.printProject.printLayers[Global.printer.layerIndex]);
                Global.printProject.printLayers.RemoveAt(Global.printer.layerIndex + 1);
                int temp = Global.printer.layerIndex;
                Global.MainVM.flushDgv();
                SelectedItem = DataGridLists[Global.printer.layerIndex - 1];
                Global.printer.layerIndex = SelectedItem.层序号 - 1;
            }
            catch
            { }
        }

        private void MoveUp()
        {
            try
            {
                if (Global.printProject.printLayers.Count == 0)
                {
                    MessageBox.Show("无数据!");
                    return;
                }
                if (Global.printer.layerIndex == Global.printProject.printLayers.Count)
                {
                    MessageBox.Show("已经是最后一行了!");
                    return;
                }
                if (Global.printer.layerIndex + 2 > Global.printProject.printLayers.Count)
                    Global.printProject.printLayers.Add(Global.printProject.printLayers[Global.printer.layerIndex]);
                else
                    Global.printProject.printLayers.Insert(Global.printer.layerIndex + 2, Global.printProject.printLayers[Global.printer.layerIndex]);
                Global.printProject.printLayers.RemoveAt(Global.printer.layerIndex);
                int temp = Global.printer.layerIndex;
                Global.MainVM.flushDgv();
                SelectedItem = DataGridLists[Global.printer.layerIndex];
                Global.printer.layerIndex = SelectedItem.层序号;
            }
            catch
            { }
        }
        private int _IsChangeAirPress = 0;
        public int IsChangeAirPress
        {
            get => _IsChangeAirPress;
            set => Set(ref _IsChangeAirPress, value);
        }
        /// <summary>
        /// 借气打印
        /// </summary>
        /// <param name="layer">0: 未分配；1: 已分配；2: 其他通道</param>
        /// <param name="level">0：单层；1：全部层</param>
        /// <returns></returns>
        private int ChangeAirPress(PrintLayer layer, int level)
        {
            if (layer.channel == 6)
            {
                var request = MessageBox.Show("该通道是否分配气阀？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (request == DialogResult.Yes)
                {
                    _IsChangeAirPress = 1;
                    return 1;
                }
                else
                {
                    _IsChangeAirPress = 0;
                    TotalCount = "请为通道7分配气阀后,再开始打印！";
                    return 0;
                }
            }
            else
            {
                _IsChangeAirPress = 2;
                return 2;
            }
        }
        /// <summary>
        /// 打印当前层
        /// </summary>
        private void PrintCurrentLayer()
        {
            if (!Global.printer.serialPortController.serialPort.IsOpen)
            {
                MessageBox.Show("串口未打开！");
                return;
            }
            if (Global.printer.layerIndex == -1)
            {
                MessageBox.Show("无打印层！");
                return;
            }
            if (Global.printer.printerState != 0)
            {
                MessageBox.Show("正在打印，请稍后再试！");
                return;
            }
            Thread thread = new Thread(new ThreadStart(LoadOneLayerData))
            {
                IsBackground = true
            };
            thread.Start();
        }
        private void LoadOneLayerData()
        {
            TotalCount = "正在设置通道...";
            PrintLayer currPrintLayer = Global.printProject.printLayers[Global.printer.layerIndex];
            int currPrintChannel = currPrintLayer.channel;
            //if (ChangeAirPress(currPrintLayer, 0) == 0)
            //    return;

            //打印一层之前先设定当前层的通道
            Global.MainVM.setChannel(currPrintChannel);
            //移动到通道打印起点
            Point3D currentPoint3D = Global.printProject.printChannels[currPrintChannel].position;
            //float relativeX = currentPoint3D.X;
            //float relativeY = currentPoint3D.Y;
            //float relativeZ = currentPoint3D.Z;
            float relativeX = Global.WindowXYZVM.CurrentPosition.X;
            float relativeY = Global.WindowXYZVM.CurrentPosition.Y;
            float relativeZ = Global.WindowXYZVM.CurrentPosition.Z;
            if (relativeX > 0 || relativeY > 0 || relativeZ > 0)
                Global.printer.moveToAbsolute(relativeX, relativeY, relativeZ);
            //float jdX = float.Parse(Global.WindowXYZVM.XValue);
            //float jdY = float.Parse(Global.WindowXYZVM.YValue);
            //float jdZ = float.Parse(Global.WindowXYZVM.ZValue);

            List<Point3D> points = currPrintLayer.points;
            TotalCount = "正在发送路径指令";
            double step = 100.0 / points.Count;
            bool isFirstStopPoint = true; // 用于标记是否是第一个停止点

            int prepare = int.Parse(Global.SliceParaVM.PrepareList[Global.SliceParaVM.PrepareSelectedIndex]); //预挤压
            int delay = int.Parse(Global.SliceParaVM.DelayList[Global.SliceParaVM.DelaySelectedIndex]); //延时
            for (int i = 0; i < points.Count; i++)
            {
                //预挤压等待
                if (prepare > 0 && i == 1)
                {
                    Global.printer.DelayWaiting(prepare);
                }
                System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    Progress += step;
                    Global.printStatusVM.PrintStatuslbl = "工作中";
                }));
                //if (jdX > 0 || jdY > 0 || jdZ > 0)
                //{
                //    points[i].X += jdX;
                //    points[i].Y += jdY;
                //    points[i].Z += jdZ;
                //}
                //if (relativeX > 0 || relativeY > 0 || relativeZ > 0)
                //{
                //    points[i].X += relativeX;
                //    points[i].Y += relativeY;
                //    points[i].Z += relativeZ;
                //}
                if (Global.StopPrintPoints.Any(stopPoint =>
            Math.Abs(points[i].X - stopPoint.X) < double.Epsilon &&
            Math.Abs(points[i].Y - stopPoint.Y) < double.Epsilon))
                {
                    int stopIndex = Global.StopPrintPoints.FindIndex(stopPoint =>
                        Math.Abs(points[i].X - stopPoint.X) < double.Epsilon &&
                        Math.Abs(points[i].Y - stopPoint.Y) < double.Epsilon
                    );

                    // 如果是第一个停止点，先发送气压指令，再移动到该点
                    if (isFirstStopPoint)
                    {
                        if (stopIndex % 2 == 0)
                        {
                            Global.printProject.printChannels[currPrintChannel].setAirPress(); // 开始指令
                            isFirstStopPoint = false; // 标记已处理第一个停止点
                            Global.printer.moveToAbsolute(points[i].X + relativeX, points[i].Y + relativeY, points[i].Z + relativeZ);
                            //Global.printer.toPoint(points[i]);
                        }
                    }
                    else
                    {
                        if (stopIndex % 2 == 0)
                        {
                            Global.printer.moveToAbsolute(points[i].X + relativeX, points[i].Y + relativeY, points[i].Z + relativeZ);
                            //Global.printer.toPoint(points[i]); // 移动到该点
                            Global.printProject.printChannels[currPrintChannel].setAirPress(); // 开始指令
                        }
                        else
                        {
                            Global.printer.moveToAbsolute(points[i].X + relativeX, points[i].Y + relativeY, points[i].Z + relativeZ);
                            //Global.printer.toPoint(points[i]); // 移动到该点
                            MainWindow.printer.SendGCode("G1P" + Utilities.pressureTocurrent(0).ToString("0.0")); // 停止指令
                        }
                    }
                }
                else
                    //Global.printer.toPoint(points[i]);
                    Global.printer.moveToAbsolute(points[i].X + relativeX, points[i].Y + relativeY, points[i].Z + relativeZ);

                //后挤压等待
                if (delay > 0 && i == points.Count - 1)
                {
                    Global.printProject.printChannels[currPrintChannel].setAirPress();
                    Global.printer.DelayWaiting(delay);
                }
            }
            //打印完一层后将气压设置为0
            //Global.printer.channelIndex = 6;
            //Global.MainVM.setChannel(Global.printer.channelIndex);
            if (Global.printLayer.mode <= 2)
                MainWindow.printer.SendGCode("G1P" + Utilities.pressureTocurrent(0).ToString("0.0")); // 停止指令
            if (IsZeroChecked)
            {
                //原 直接回到0,0点太高Z轴3,然后回归0,0,0点
                //Global.printer.moveToSolidifyZero1(points[points.Count - 1].Z);
                //Global.printer.moveToAbsolute(0, 0, 0);

                Global.printer.moveToAbsolute(points[points.Count - 1].X + relativeX, points[points.Count - 1].Y + relativeY, points[points.Count - 1].Z + relativeZ + 3);
                Global.printer.moveToAbsolute(Global.WindowXYZVM.CurrentPosition.X, Global.WindowXYZVM.CurrentPosition.Y, Global.WindowXYZVM.CurrentPosition.Z);
                //Global.MainVM.closeSolidfyLight.Start();
            }
            else
                Global.printer.printToAbsolute(points[points.Count - 1].X, points[points.Count - 1].Y, points[points.Count - 1].Z + 3);
            TotalCount = "指令发送完成";
            if (currPrintLayer.CuringLamp)
            {
                TotalCount += "\r\n等待固化";
                CalculateCenterPointAsync(points);
            }
            TotalCount = "";
            Progress = 0;
            Global.printStatusVM.PrintStatuslbl = "停止";
        }
        private void setChannel(int index)
        {
            Global.printer.channelIndex = index;
            if (Global.printer.channelIndex < 6)
            {
                PrintChannel.setChannel(Global.printProject.printChannels[index].ChannelID);
            }
            Global.printProject.printChannels[Global.printer.channelIndex].setAirPress();
            Global.printProject.printChannels[Global.printer.channelIndex].setPrintSpeed();
            Global.printProject.printChannels[Global.printer.channelIndex].setT1T2T3();
        }
        /// <summary>
        /// 打印所有层
        /// </summary>
        private void PrintAllLayer()
        {
            if (!Global.printer.serialPortController.serialPort.IsOpen)
            {
                MessageBox.Show("串口未打开！");
                return;
            }
            if (Global.printer.layerIndex == -1)
            {
                MessageBox.Show("无打印层！");
                return;
            }
            if (Global.printer.printerState != 0)
            {
                MessageBox.Show("正在打印，请稍后再试！");
                return;
            }
            DialogResult RSS = MessageBox.Show("是否需要设置起始层？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            switch (RSS)
            {
                case DialogResult.Yes:
                    PrintParaView printPara = new PrintParaView();
                    printPara.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
                    printPara.ShowDialog();
                    break;
                case DialogResult.No:
                    break;
            }
            Global.printer.layerIndex = 0;
            HasHalfLayersProcessed = false;
            Thread thread = new Thread(new ThreadStart(LoadLayerData))
            {
                IsBackground = true
            };
            thread.Start();
            int i = 0;
        }
        public int CountNum = 1;
        public bool HasHalfLayersProcessed;
        public int tempIndex = -1;
        public List<PrintLayer> originalLayers = new List<PrintLayer>();
        public void LoadLayerData()
        {
            try
            {
                float averageZOffset = 0;
                bool isInterLayer = false;
                if (Global.SliceParaVM.PrintModeSelectedIndex == 1 && !HasHalfLayersProcessed)
                {
                    originalLayers = Global.printProject.printLayers;
                    int x = (int)Math.Floor((double)originalLayers.Count / 2);
                    tempIndex = x;
                    averageZOffset = originalLayers[x].points[0].Z - originalLayers[0].points[0].Z;
                    var tempLayers = originalLayers.GetRange(x, originalLayers.Count - x); // 这里只修改tempLayers，不修改Global.printProject.printLayers

                    foreach (var layer in tempLayers)
                    {
                        foreach (var point in layer.points)
                        {
                            point.Z = (float)Math.Round(point.Z - averageZOffset, 1);
                        }
                    }
                    // 将修改后的tempLayers赋值回Global.printProject.printLayers，仅在需要的时候
                    Global.printProject.printLayers = tempLayers;
                    HasHalfLayersProcessed = true;
                }
                PrintLayer currPrintLayer = Global.printProject.printLayers[Global.printer.layerIndex];
                //if (Global.printer.layerIndex>0)
                //    return;
                int currPrintChannel = currPrintLayer.channel;
                List<Point3D> points = currPrintLayer.points;
                TotalCount = "第" + CountNum + "层指令发送中";
                Point3D currentPoint3D = Global.printProject.printChannels[currPrintChannel].position;
                //float relativeX = currentPoint3D.X;
                //float relativeY = currentPoint3D.Y;
                //float relativeZ = currentPoint3D.Z;
                float relativeX = Global.WindowXYZVM.CurrentPosition.X;
                float relativeY = Global.WindowXYZVM.CurrentPosition.Y;
                float relativeZ = Global.WindowXYZVM.CurrentPosition.Z;

                //if (IsChangeAirPress != 1)
                //{
                //    if (ChangeAirPress(currPrintLayer, 1) == 0)
                //        return;
                //}

                //Global.printer.channelIndex = Global.printProject.printLayers[Global.printer.layerIndex].channel;
                if (points.Count > 0)
                    Global.printer.moveToAbsolute(points[0].X + relativeX, points[0].Y + relativeY, points[0].Z + relativeZ);
                //Global.printer.toPoint(points[0]);//该行是为了正确移动到打印顶点
                Global.MainVM.setChannel(currPrintChannel);//打印一层之前先设定当前层的通道
                                                           //Global.MainVM.setChannel(Global.printProject.printLayers[Global.printer.layerIndex].channel);//打印一层之前先设定当前层的通道
                double step = Math.Round(100.0 / points.Count, 2);
                bool isFirstStopPoint = true; // 用于标记是否是第一个停止点
                for (int j = 1; j < points.Count; j++)
                {
                    if (isInterLayer)
                        points[j].Z += (float)Math.Floor(float.Parse(Global.SliceParaVM.MaxHeight) * 10 / 2) / 10;
                    Progress += step;
                    if (Global.StopPrintPoints.Any(stopPoint =>
                Math.Abs(points[j].X - stopPoint.X) < double.Epsilon &&
                Math.Abs(points[j].Y - stopPoint.Y) < double.Epsilon))
                    {
                        int stopIndex = Global.StopPrintPoints.FindIndex(stopPoint =>
                            Math.Abs(points[j].X - stopPoint.X) < double.Epsilon &&
                            Math.Abs(points[j].Y - stopPoint.Y) < double.Epsilon
                        );

                        // 如果是第一个停止点，先发送气压指令，再移动到该点
                        if (isFirstStopPoint)
                        {
                            if (stopIndex % 2 == 0)
                            {
                                Global.printProject.printChannels[currPrintChannel].setAirPress(); // 开始指令
                                isFirstStopPoint = false; // 标记已处理第一个停止点
                                                          //Global.printer.toPoint(points[j]);
                                Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ);
                            }
                            else
                            {
                                Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ);
                                Global.printer.toPoint(points[j]);
                                isFirstStopPoint = false; // 标记已处理第一个停止点
                                MainWindow.printer.SendGCode("G1P" + Utilities.pressureTocurrent(0).ToString("0.0")); // 停止指令
                                                                                                                      //Global.printer.printToAbsolute(points[j].X, points[j].Y, points[j].Z + 2);
                                Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ + 2);
                                isInterLayer = true;
                            }
                        }
                        else
                        {
                            if (stopIndex % 2 == 0)
                            {
                                Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ);
                                //Global.printer.toPoint(points[j]); // 移动到该点
                                Global.printProject.printChannels[currPrintChannel].setAirPress(); // 开始指令
                            }
                            else
                            {
                                Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ);
                                //Global.printer.toPoint(points[j]); // 移动到该点
                                MainWindow.printer.SendGCode("G1P" + Utilities.pressureTocurrent(0).ToString("0.0")); // 停止指令
                                                                                                                      //Global.printer.printToAbsolute(points[j].X, points[j].Y, points[j].Z + 2);
                                Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ + 2);
                                //isInterLayer = false;
                                isInterLayer = true;
                            }
                        }
                    }
                    else
                        Global.printer.moveToAbsolute(points[j].X + relativeX, points[j].Y + relativeY, points[j].Z + relativeZ);
                    //Global.printer.toPoint(points[j]);
                }

                Progress = 100;
                Global.printStatusVM.PrintStatuslbl = "停止";
                Global.printer.channelIndex = 6;

                //if (Global.printLayer.mode <= 2)
                if (currPrintLayer.mode <= 2)
                    MainWindow.printer.SendGCode("G1P" + Utilities.pressureTocurrent(0).ToString("0.0")); // 停止指令
                if (IsZeroChecked && Global.printer.layerIndex == Global.printProject.printLayers.Count - 1
                    && Global.printProject.printLayers.Count() >= originalLayers.Count())
                {
                    Global.printer.moveToAbsolute(points[points.Count - 1].X + relativeX, points[points.Count - 1].Y + relativeY, points[points.Count - 1].Z + relativeZ + 3);
                    Global.printer.moveToAbsolute(Global.WindowXYZVM.CurrentPosition.X, Global.WindowXYZVM.CurrentPosition.Y, Global.WindowXYZVM.CurrentPosition.Z);
                    //Global.printer.moveToSolidifyZero1(points[points.Count - 1].Z);
                    //Global.printer.moveToAbsolute(0, 0, 0);
                    //Global.MainVM.timerIsStop.Start(); //暂时注释
                }
                //else
                //    Global.printer.printToAbsolute(points[points.Count - 1].X, points[points.Count - 1].Y, points[points.Count - 1].Z + 2);
                TotalCount = "第" + CountNum + "层指令发送完成";
                Global.printer.SendGCode(TotalCount);
                if (currPrintLayer.CuringLamp)
                {
                    TotalCount += "\r\n等待固化";
                    CalculateCenterPointAsync(points);
                }
                Global.MainVM.timerIsStop.Start(); //暂时注释
            }
            catch (Exception ex)
            {
                Global.LogHelper.WriteLog("打印全部层LoadLayerData():" + ex.Message + ex.StackTrace);
            }
        }
        /// <summary>
        /// 打印完一层后计算中心点 移动后静止开启固化灯
        /// </summary>
        /// <param name="point3D"></param>
        public void CalculateCenterPointAsync(List<Point3D> point3D)
        {
            float minX = point3D.Min(p => p.X);
            float maxX = point3D.Max(p => p.X);
            float minY = point3D.Min(p => p.Y);
            float maxY = point3D.Max(p => p.Y);
            float maxZ = point3D.Max(p => p.Z);
            float centerX = (minX + maxX) / 2;
            float centerY = (minY + maxY) / 2;
            Point3D point = new Point3D();
            point.X = (float)centerX;
            point.Y = (float)centerY;
            point.Z = (float)maxZ + 3;
            Global.printer.toPoint(point);
            Global.printer.SendGCode("M250");
            Thread.Sleep(2000);
            Global.printer.SendGCode("M251");
        }
        /// <summary>
        /// 回到打印原点
        /// </summary>
        private void GoHome()
        {
            try
            {
                if (Global.printProject.printLayers.Count == 0)
                    return;
                int channel = Global.printProject.printLayers[Global.printer.layerIndex].channel;
                Point3D point = Global.printProject.printLayers[Global.printer.layerIndex].points[0];
                Global.printer.moveToRelative(point.X + Global.printProject.printChannels[channel].position.X,
                                            point.Y + Global.printProject.printChannels[channel].position.Y,
                                            point.Z, channel);
            }
            catch (Exception ex)
            {
                Global.LogHelper.WriteLog("回到打印原点GoHome():" + ex.Message + ex.StackTrace);
            }
            //Global.printer.moveToRelative(point.X, point.Y, point.Z, Global.printProject.printLayers[Global.printer.layerIndex].channel);
        }
        /// <summary>
        /// 结束打印
        /// </summary>
        private void EndPrint()
        {
            Global.printer.Pause();
            if (MessageBox.Show("确定要结束打印吗？", "确认结束打印", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Global.printer.Cancel();
                PrintStatus = "暂停打印";
                isPrintPaused = false;
            }
            else
            {
                PrintStatus = "恢复打印"; 
                isPrintPaused = true;
            }

        }
        private bool isPrintPaused = false;
        /// <summary>
        /// 暂停打印
        /// </summary>
        private void PausePrint()
        {
            if (!isPrintPaused)
            {
                // 暂停打印
                Global.printer.Pause();
                PrintStatus = "恢复打印";
                isPrintPaused = true;
            }
            else
            {
                // 恢复打印
                Global.printer.Continue();
                PrintStatus = "暂停打印";
                isPrintPaused = false;
            }
        }

        public void DataGrid_SelectionChanged(int index)
        {
            if (index > 0)
                changeLayer(index - 1);
            else
                ImageSource = null;
        }

        int multiply = 3;
        Bitmap bmp;
        Graphics graphics;
        private void changeLayer(int index)
        {
            Global.printer.layerIndex = index;
            //Global.printer.layerIndex = Global.SliceVM.DataGridLists[index].打印通道;
            PrintLayer currentLayer = Global.printProject.printLayers[index];
            Global.printer.channelIndex = currentLayer.channel;
            //if (dgvPrintLayer.SelectedRows.Count > 0)
            if (index >= 0)
            {
                //PrintChannel currentLayerIndex = Global.printProject.printChannels[Global.printer.layerIndex - 1];
                PrintChannel currentLayerIndex = Global.printProject.printChannels[Global.SliceVM.DataGridLists[index].打印通道 - 1];
                Number = "" + (Global.printer.layerIndex + 1);
                StartPoint = currentLayerIndex.position.X.ToString("0.00") + " mm * "
                            + currentLayerIndex.position.Y.ToString("0.00") + " mm * "
                            + currentLayerIndex.position.Z.ToString("0.00");
                OriginalPoint = currentLayer.x_start.ToString("0.00") + "mm *"
                    + currentLayer.y_start.ToString("0.00") + "mm *"
                    + currentLayer.z_start.ToString("0.00");

                //StartPoint = currentLayer.x_start.ToString("0.00") + " mm * " + currentLayer.y_start.ToString("0.00") + " mm * " + currentLayer.z_start.ToString("0.00");
                //OriginalPoint = Math.Abs(currentLayer.x_start - currentLayerIndex.position.X)  + "mm *" +
                //                (currentLayer.y_start - currentLayerIndex.position.Y) + "mm *" +
                //                (currentLayer.z_start - currentLayerIndex.position.Z);

                Size = currentLayer.x_size.ToString("0.00") + " mm * " + currentLayer.y_size.ToString("0.00");
                Interval = currentLayer.interval.ToString();
                FixEvent = currentLayer.solidfyTime.ToString();
            }
            else
            {
                Number = "";
                StartPoint = "";
                OriginalPoint = "";
                Size = "";
                Interval = "";
                FixEvent = "";
            }
            bmp = new Bitmap((int)Global.printer.maxY * multiply, (int)Global.printer.maxX * multiply);
            graphics = Graphics.FromImage(bmp);
            if (currentLayer.points.Count != 0)
            {
                Point3D begin = currentLayer.points[0];
                for (int i = 1; i < currentLayer.points.Count; i++)
                {
                    Point3D next = currentLayer.points[i];
                    if (next.mode == 1 || next.mode == 0)
                    {
                        graphics.DrawLine(new Pen(Color.Black, 2), begin.X * multiply * ViewWidth, begin.Y * multiply * ViewHeight, next.X * multiply * ViewWidth, next.Y * multiply * ViewHeight);
                        //graphics.DrawLine(new Pen(Color.Black, 2), float.Parse((begin.Y * multiply).ToString()), float.Parse((begin.X * multiply).ToString()), float.Parse((next.Y * multiply).ToString()), float.Parse((next.X * multiply).ToString()));
                    }
                    begin = next;
                }
            }
            ImageSource = BitmapToBitmapImage(bmp);
        }
        private BitmapImage BitmapToBitmapImage(Bitmap bitmap)
        {
            if (bitmap == null)
                return null;

            using (var memory = new MemoryStream())
            {
                bitmap.Save(memory, ImageFormat.Png); // 或者其他你需要的格式  
                memory.Position = 0;
                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                return bitmapImage;
            }
        }
        public ICommand AddCommand { get; private set; }
        public ICommand DeleteCommand { get; private set; }
        public ICommand EditCommand { get; private set; }
        public ICommand MoveDownCommand { get; private set; }
        public ICommand MoveUpCommand { get; private set; }
        public ICommand DeleteAllCommand { get; private set; }
        public ICommand EditAllCommand { get; private set; }


        public ICommand SetCuringLampCommand { get; private set; }
        public ICommand SetAllCuringLampCommand { get; private set; }
        public ICommand PrintCurrentLayerCommand { get; private set; }
        public ICommand PrintAllLayerCommand { get; private set; }
        public ICommand GoHomeCommand { get; private set; }
        public ICommand PausePrintCommand { get; private set; }
        public ICommand EndPrintCommand { get; private set; }
        public ICommand CellClick { get; private set; }
        private PrintSliceItem _SelectedItem;
        public PrintSliceItem SelectedItem
        {
            get => _SelectedItem;
            set => Set(ref _SelectedItem, value);
        }
        private BitmapImage _ImageSource;
        public BitmapImage ImageSource
        {
            get => _ImageSource;
            set => Set(ref _ImageSource, value);
        }
        private ObservableCollection<PrintSliceItem> _DataGridLists = new ObservableCollection<PrintSliceItem>();
        public ObservableCollection<PrintSliceItem> DataGridLists
        {
            get => _DataGridLists;
            set => Set(ref _DataGridLists, value);
        }
        private bool _IsZeroChecked = true;
        public bool IsZeroChecked
        {
            get => _IsZeroChecked;
            //set => Set(ref _IsZeroChecked, value);
            set
            {
                if (_IsZeroChecked != value)
                {
                    _IsZeroChecked = value;
                    Set(ref _IsZeroChecked, value);
                }
            }
        }
        //PrintSliceDataGridItems
        private string _PrintStatus = "暂停打印";
        public string PrintStatus
        {
            get => _PrintStatus;
            set => Set(ref _PrintStatus, value);
        }

        private string _Number = "0";
        public string Number
        {
            get => "当前层序号：" + _Number;
            set => Set(ref _Number, value);
        }

        private string _StartPoint = "0";
        public string StartPoint
        {
            get => "起点：" + _StartPoint + " mm";
            set => Set(ref _StartPoint, value);
        }
        private string _OriginalPoint = "0";
        public string OriginalPoint
        {
            get => "偏移量：" + _OriginalPoint + " mm";
            set => Set(ref _OriginalPoint, value);
        }

        private string _Size = "0";
        public string Size
        {
            get => "尺寸：" + _Size + " mm";
            set => Set(ref _Size, value);
        }

        private string _Interval = "0";
        public string Interval
        {
            get => "间隔：" + _Interval + " mm";
            set => Set(ref _Interval, value);
        }

        private string _FixEvent = "0";
        public string FixEvent
        {
            get => "固化时间：" + _FixEvent + " s";
            set => Set(ref _FixEvent, value);
        }
        private string _TotalCount;
        public string TotalCount
        {
            get => _TotalCount;
            set => Set(ref _TotalCount, value);
        }
        private double _Progress;
        public double Progress
        {
            get => _Progress;
            set => Set(ref _Progress, value);
        }
        private bool _IsEnbaled = false;
        public bool IsEnbaled
        {
            get => _IsEnbaled;
            set => Set(ref _IsEnbaled, value);
        }
        private float viewWidth;
        public float ViewWidth
        {
            get => viewWidth;
            set => Set(ref viewWidth, value);
        }
        private float viewHeight;
        public float ViewHeight
        {
            get => viewHeight;
            set => Set(ref viewHeight, value);
        }
        private List<int> _SelectedIndices;
        public List<int> SelectedIndices
        {
            get => _SelectedIndices;
            set => Set(ref _SelectedIndices, value);
        }
    }
}
